package com.my.zuji.service;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.my.zuji.controller.form.LoginForm;
import com.my.zuji.controller.form.RegisteForm;
import com.my.zuji.domain.bookkeeping.Account;
import com.my.zuji.domain.bookkeeping.BookingCategory;
import com.my.zuji.domain.bookkeeping.Member;
import com.my.zuji.domain.bookkeeping.Project;
import com.my.zuji.domain.bookkeeping.Seller;
import com.my.zuji.domain.bookkeeping.User;
import com.my.zuji.repository.AccountRepository;
import com.my.zuji.repository.CategoryRepository;
import com.my.zuji.repository.MemberRepository;
import com.my.zuji.repository.ProjectRepository;
import com.my.zuji.repository.SellerRepository;
import com.my.zuji.repository.UserRepository;

@Service
public class PublicServiceImpl implements PublicService {
	
	@Autowired
	private UserRepository userRepository;
	
	@Autowired
	private CategoryRepository ctegoryRepository;
	
	@Autowired
	private AccountRepository accountRepository;
	
	@Autowired
	private MemberRepository memberRepository ;
	
	@Autowired
	private ProjectRepository projectRepository;
	
	@Autowired
	private SellerRepository sellerRepository;

	@Override
	public Boolean checkUserName(String userName) {
		return userRepository.findByUserName(userName)==null?true:false;
	}
	
	@Override
	@Transactional
	public void register(RegisteForm registeForm) {
		User user = new User();
		BeanUtils.copyProperties(registeForm, user);
		userRepository.save(user);
	}

	@Override
	public User login(LoginForm loginForm) {
		String name = loginForm.getUserName();
		String ps = loginForm.getPassword();
		return userRepository.findByUserNameAndPassword(name, ps);
	}

	@Override
	public Map<BookingCategory, List<BookingCategory>> findCategoryByName(String payType) {
		Map<BookingCategory, List<BookingCategory>> bookingCategoryMap = new LinkedHashMap<BookingCategory, List<BookingCategory>>();
		BookingCategory payTypeCategory = ctegoryRepository.findByName(payType);
		List<BookingCategory>  oneLevelCtegorys = ctegoryRepository.findByParentOrderBySortIndexAsc(payTypeCategory);
		for(BookingCategory mapKey:oneLevelCtegorys){
			List<BookingCategory> mapValue = ctegoryRepository.findByParentOrderBySortIndexAsc(mapKey);
			bookingCategoryMap.put(mapKey, mapValue);
		}
		return bookingCategoryMap;
	}

	@Override
	public List<Account> findAccountByUser(User user) {
		return accountRepository.findByUser(user);
	}

	@Override
	public List<Member> findAllMemberByUser(User user) {
		return memberRepository.findByUser(user);
	}

	@Override
	public List<Project> findProjectByUser(User user) {
		return projectRepository.findByUser(user);
	}
	
	public List<Project> findProjectByUser2(final User user) {
		return projectRepository.findAll(new Specification<Project>(){
			@Override
			public Predicate toPredicate(Root<Project> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> list = new ArrayList<Predicate>();
				list.add(cb.equal(root.get("user").as(User.class),user));
				return cb.and(list.toArray(new Predicate[list.size()]));
			}
		});
	}

	@Override
	public List<Seller> findSellerByUser(User user) {
		return sellerRepository.findByUser(user);
	}
}
